<template>
  <!-- :row-selection="rowSelection" -->
  <BoTable
    :columns="columns"
    :request="_areaEvent"
    row-key="contractId"
    ref="tableRef"
  >
    <template #leftContainer>
      <div class="mr-4 w-48 border-r border-[rgba(255,255,255,.3)]">
        <div class="module-title detection">关联监测阵</div>
        <Tree
          v-if="treeData.length"
          :tree-data="treeData"
          show-icon
          default-expand-all
        >
          <template #title="scope">
            <span @click="() => handleSelectStructure(scope)">{{
              scope.structureName
            }}</span>
          </template>
        </Tree>
      </div>
    </template>
    <template #toolbars>
      <Space :size="8">
        <Button type="primary" @click="onConfig" :disabled="!canConfig">
          区域配置
        </Button>
      </Space>
    </template>
    <template #devices="{ record }">
      <div class="info" v-if="Array.isArray(record.pointDevices)">
        <div v-for="item in record.pointDevices">
          {{ item.stationId || '--' }}
        </div>
      </div>
      <div v-else>--</div>
    </template>
    <template #chufa="{ record }">
      <div class="info" v-if="Array.isArray(record.pointDevices)">
        <div v-for="item in record.pointDevices">
          {{ item.pointName || '--' }}
        </div>
      </div>
      <div v-else>--</div>
    </template>
  </BoTable>
  <FormModal :columns="item">
    <template #details="{ formState }">
      <BoTable
        :columns="_column"
        :request="_editInfo"
        height="auto"
        hideSearch
        ref="areaTableRef"
      >
        <template #toolbars>
          <Space :size="8">
            <Button type="primary" @click="onOperation(null)">
              新增区域
            </Button>
          </Space>
        </template>
      </BoTable>
    </template>
  </FormModal>

  <FormModal2 :columns="_item" :model="addInfo">
    <template #label>
      <div class="modal_title">区域信息</div>
    </template>
    <template #label1>
      <div class="modal_title">测点信息</div>
    </template>
    <template #placeholder>
      <div></div>
    </template>
    <template #details>
      <FormItemRest>
        <BoTable
          :columns="_columns2"
          :request="_addInfo"
          height="auto"
          :row-selection="_rowSelection"
          row-key="id"
        >
        </BoTable>
      </FormItemRest>
    </template>
  </FormModal2>
  <Modal
    v-model:open="flag"
    @ok="handleOk"
    :footer="false"
    wrapClassName="view_modal"
    :destroyOnClose="true"
  >
    <triggerData
      :deviceInfo="deviceInfo"
      v-model:showWitch="showWitch"
      :title="showWitch === 'trigger' ? '设备触发数据' : '数据产出'"
      :fetchInfoApi="() => waveInfo"
      :data="dataInfo"
      :options="option"
    >
      <template #header v-if="showWitch == 'trigger'">
        <!-- <div class="custom_header">
          <div>
            <div>设备标识:</div>
            <div>{{ '--' }}</div>
          </div>
          <div>
            <div>采样率:</div>
            <div>{{ '--' }}</div>
          </div>
          <div>
            <div>仪器烈度:</div>
            <div>{{ '--' }}</div>
          </div>
        </div> -->
      </template>
    </triggerData>
  </Modal>

  <!-- 预览pdf -->
  <BoPreviewPdf
    title="预览"
    :iframe-url="iframeUrl"
    v-model:open="visible"
  ></BoPreviewPdf>

  <FormModal3 :columns="_items">
    <template #details>
      <div class="generate_error_msg">
        {{ generateErrorMsg || '-' }}
      </div>
    </template>
  </FormModal3>

  <globalLoading v-model:visible="showLoading" tip="图表生成中..." />
</template>

<route lang="json">
{
  "name": "强震区域产出",
  "meta": { "title": "强震区域产出" }
}
</route>

<script setup lang="tsx">
import { computed, nextTick, provide, ref, watch } from 'vue';
import { useFormModal } from '@boeyo/hooks';
import { useDicts, useUserStore } from '@boeyo/portal';
import { download } from '@boeyo/shared';
import { BoFormProps, BoPreviewPdf, BoTable, BoTableProps } from '@boeyo/ui';
import {
  Button,
  FormItemRest,
  Modal,
  Space,
  Tree,
  message,
} from 'ant-design-vue';
import dayjs from 'dayjs';
import { pick } from 'lodash-es';
import globalLoading from '@/components/globalLoading/index.vue';
import triggerData from '@/components/triggerData/index.vue';
import { getWaveInfo } from '@/utils/index';
import {
  areaConfigList,
  areaEvent,
  createEarthquakeData,
  downloadGenerateById,
  fetchHistoryData,
  getInfo,
  responseSpectrum,
  saveOrUpdate,
  signal,
  tree,
} from './api';

const userStore = useUserStore();
const license = userStore.license;

const generateErrorMsg = ref('');
const validator = (rule: any, value: any, callback: any) => {
  if (addInfo.value.pointCount > _selectKeys.value.length) {
    return Promise.reject('当前选中测点少于最少触发测点数!');
  }
  return Promise.resolve();
};
const _areaEvent = (queryParams: any) => {
  queryParams.startTime = queryParams.time?.[0];
  queryParams.endTime = queryParams.time?.[1];
  return areaEvent({ ...queryParams, ...params });
};
const { pointTypeEnum } = useDicts(['point_type']);
const treeData = ref([]);

const getTreeData = async () => {
  const res = await tree({});
  treeData.value = res.data;
};
getTreeData();

const _editInfo = () => {
  return areaConfigList({ structureId: params.structureId });
};
const addInfo: any = ref({});

const _addInfo = (queryParams: any) => {
  return getInfo({
    ...pick(params, ['structureId', 'alarmId']),
    ...queryParams,
  });
};
const { FormModal, open } = useFormModal({
  size: 'middle',
  column: 1,
});
const { FormModal: FormModal2, open: open2 } = useFormModal({
  size: 'middle',
  column: 2,
});

const { FormModal: FormModal3, open: open3 } = useFormModal({
  size: 'middle',
  column: 1,
});

const _items = computed<BoFormProps['columns']>(() => [
  {
    title: '',
    dataIndex: 'details',
    valueType: 'input',
    formItemProps: {
      wrapperCol: { span: 24 },
    },
  },
]);

const _info = (params: any) => {
  params.id = logId.value;
  params.type = 1;
  return {
    total: 0,
    rows: [],
  };
};

const _columns = computed<BoTableProps['columns']>(() => [
  {
    title: '操作时间',
    dataIndex: 'time',
  },
]);

const columns = computed<BoTableProps['columns']>(() => [
  {
    title: '所属项目',
    dataIndex: 'projectName',
  },
  {
    title: '触发时间',
    dataIndex: 'time',
    valueType: 'dateRange',
    hideInTable: true,
  },
  {
    title: '触发区域',
    dataIndex: 'areaName',
    hideInSearch: true,
  },
  {
    title: '触发测点',
    dataIndex: 'chufa',
    hideInSearch: true,
  },
  {
    title: '测点数',
    dataIndex: 'count',
    hideInSearch: true,
    customRender({ record }) {
      if (Array.isArray(record.pointDevices))
        return <span>{record.pointDevices.length}</span>;
      return <></>;
    },
  },
  {
    title: '区域测点总数',
    dataIndex: 'areaPointCount',
    hideInSearch: true,
  },
  {
    title: '关联设备',
    dataIndex: 'devices',
    hideInSearch: true,
  },
  {
    title: '开始时间',
    dataIndex: 'startTime',
    hideInSearch: true,
  },
  {
    title: '结束时间',
    dataIndex: 'endTime',
    hideInSearch: true,
  },
  {
    title: '时间时长(s)',
    dataIndex: 'time',
    hideInSearch: true,
    customRender({ record }) {
      if (record.startTime && record.endTime) {
        const start = dayjs(record.startTime);
        const end = dayjs(record.endTime);
        const result = end.diff(start, 'millisecond') / 1000;
        return <span>{result}</span>;
      }
      return <></>;
    },
  },
  {
    title: '产出数据',
    dataIndex: 'operation',
    hideInSearch: true,
    fixed: 'right',
    actions: [
      {
        text: '设备触发数据',
        onClick(record) {
          onDevices(record, 'trigger');
        },
      },
      {
        text: '数据产出',
        hidden: !['3', '4', '5'].some((item) =>
          (license.vipPaks as string[]).includes(item),
        ),
        onClick(record) {
          onDevices(record, 'signalNoiseRatio');
        },
      },
    ],
  },
  {
    title: '产出报告',
    dataIndex: 'operation1',
    hideInSearch: true,
    fixed: 'right',
    actions({ record }) {
      const style = {
        color: 'red',
      };
      return [
        {
          text: record.generateId ? (
            '预览'
          ) : (
            <span>
              <span style={style}>！</span>
              <span>预览</span>
            </span>
          ),
          onClick: async (record) => {
            if (!record.generateId) {
              generateErrorMsg.value = record.generateErrorMsg;
              return open3({
                title: '日志',
                modalType: 'disabled',
                hideFooter: true,
                request: async (params: any) => {},
                defaultValue: record,
              });
            }

            const result = await downloadGenerateById(record.generateId, 'pdf');
            const blob = new Blob([result.data], { type: 'application/pdf' });
            const imageUrl = URL.createObjectURL(blob);
            iframeUrl.value = imageUrl;
            visible.value = true;
          },
        },
        {
          text: '重新生成',
          hidden: canRegenerate.value,
          onClick: async (record) => {
            canRegenerate.value = true;
            message.loading('报告重新生成中..', 0);
            const res = await createEarthquakeData(record.eventId);
            message.destroy();
            if (res.code === 200) {
              message.success('报告生成完毕!');
            } else {
              message.info(res.msg);
            }
            canRegenerate.value = false;
            tableRef.value.refresh();
          },
        },
        {
          text: '下载',
          hidden: !record.generateId,
          onClick: async (record) => {
            const res = await downloadGenerateById(record.generateId, 'pdf');
            download(
              res.data as unknown as Blob,
              `data_${dayjs().format('YYYY-MM-DD HH:mm:ss')}.pdf`,
            );
          },
        },
      ];
    },
  },
]);
const logId = ref('');
const iframeUrl = ref();
const canRegenerate = ref(false);
const visible = ref(false);

const _column = computed<BoTableProps['columns']>(() => [
  {
    title: '区域名称',
    dataIndex: 'areaName',
  },
  {
    title: '关联测点',
    dataIndex: 'pointNames',
    customRender({ record }) {
      const pointNames = Array.isArray(record.pointList)
        ? record.pointList.map((i) => i.pointName).join(' , ')
        : '';
      return <span>{pointNames}</span>;
    },
  },
  {
    title: '时间窗',
    dataIndex: 'timeWindow',
  },
  {
    title: '最小触发测点数',
    dataIndex: 'pointCount',
  },
  {
    title: '操作',
    dataIndex: 'operation',
    hideInSearch: true,
    actions: [
      {
        text: '编辑',
        onClick(record) {
          onOperation(record);
        },
      },
      {
        text: '删除',
        onClick(record) {
          onDelete(record);
        },
      },
    ],
  },
]);
const _columns2 = computed<BoTableProps['columns']>(() => [
  {
    title: '测点编码',
    dataIndex: 'pointCode',
    hideInSearch: true,
  },
  {
    title: '测点名称',
    dataIndex: 'pointName',
  },
  {
    title: '测点位置',
    dataIndex: 'location',
  },
  {
    title: '测点类型',
    dataIndex: 'pointType',
    valueType: 'select',
    valueEnum: {
      ...pointTypeEnum.value,
    },
  },
  {
    title: '经度',
    dataIndex: 'lon',
    hideInSearch: true,
  },
  {
    title: '纬度',
    dataIndex: 'lat',
    hideInSearch: true,
  },
  {
    title: '所属项目',
    dataIndex: 'projectName',
    hideInSearch: true,
  },
  {
    title: '所属检测阵',
    dataIndex: 'structureName',
    hideInSearch: true,
  },
]);
const item = computed<BoFormProps['columns']>(() => [
  {
    title: '',
    dataIndex: 'details',
    valueType: 'input',
    formItemProps: {
      wrapperCol: { span: 24 },
    },
  },
]);
const _item = computed<BoFormProps['columns']>(() => [
  {
    title: '',
    dataIndex: 'label',
    valueType: 'editor',
    colProps: {
      span: 24,
    },
  },
  {
    title: '区域名称',
    dataIndex: 'areaName',
    valueType: 'input',
    formItemProps: {
      rules: [
        {
          required: true,
          message: '请输入区域名称',
          trigger: 'blur',
        },
      ],
      wrapperCol: { span: 18 },
      labelCol: {
        span: 6,
      },
    },
    fieldProps: {
      placeholder: '请输入区域名称',
    },
  },
  {
    title: '时间窗',
    dataIndex: 'timeWindow',
    valueType: 'inputNumber',
    formItemProps: {
      rules: [
        {
          required: true,
          message: '请输入时间窗',
          trigger: 'blur',
        },
      ],
      wrapperCol: { span: 18 },
      labelCol: {
        span: 6,
      },
    },
    fieldProps: {
      placeholder: '请输入时间窗',
      min: 1,
      addonAfter: 's',
    },
  },
  {
    title: '最少触发测点',
    dataIndex: 'pointCount',
    valueType: 'inputNumber',
    formItemProps: {
      rules: [
        {
          required: true,
          message: '请输入最少触发测点',
          trigger: 'blur',
        },
      ],
      wrapperCol: { span: 18 },
      labelCol: {
        span: 6,
      },
    },
    fieldProps: {
      placeholder: '请输入最少触发测点',
      min: 2,
    },
  },
  {
    title: '',
    dataIndex: 'label1',
    valueType: 'editor',
    colProps: {
      span: 24,
    },
  },
  {
    title: '',
    dataIndex: 'details',
    valueType: 'input',
    formItemProps: {
      wrapperCol: { span: 24 },
      // labelCol: {
      //   span: 12,
      // },
      rules: [
        {
          required: true,
          validator,
          trigger: 'blur',
        },
      ],
    },
    colProps: {
      span: 24,
    },
  },
]);
const selectKeys = ref<number[]>([]);
const rowSelection = computed<BoTableProps['rowSelection']>(() => {
  return {
    preserveSelectedRowKeys: true,
    onChange(values) {
      selectKeys.value = values as number[];
    },
  };
});

const _selectKeys = ref<number[]>([]);
const _rowSelection = computed<BoTableProps['rowSelection']>(() => {
  return {
    selectedRowKeys: _selectKeys.value,
    onChange(values) {
      _selectKeys.value = values as number[];
    },
  };
});

const onConfig = () => {
  open({
    title: '区域信息',
    request: async (params: any) => {
      message.success('操作成功!');
    },
    hideFooter: true,
    defaultValue: {},
  });
};

const areaTableRef = ref();
const onOperation = (record: any) => {
  params.alarmId = record ? record.alarmId : null;
  addInfo.value = record ? record : {};
  _selectKeys.value = record ? record.pointList.map((a) => a.pointId) : [];

  nextTick(() => {
    open2({
      title: record ? '编辑' : '新增',
      request: async () => {
        const queryParams = {
          ...addInfo.value,
          pointIds: _selectKeys.value,
          structureId: params.structureId,
        };
        await saveOrUpdate(queryParams);
        areaTableRef.value.refresh();
        _selectKeys.value = [];
      },
    });
  });
};

const onDelete = (record: any) => {
  Modal.confirm({
    title: '系统提示',
    content: `确认要删除当前选项？`,
    onOk: async () => {
      message.info('删除失败!');
    },
  });
};

const handleOk = () => {};
const flag = ref(false);
const dataInfo = ref({});
const waveInfo = ref({});
const queryParams = ref({});
const queryParams2 = computed(() => {
  const start = queryParams.value.startTime;
  const startTime = start
    ? dayjs(start).subtract(15, 'second').format('YYYY-MM-DD HH:mm:ss')
    : '';
  const endTime = start
    ? dayjs(start).subtract(5, 'second').format('YYYY-MM-DD HH:mm:ss')
    : '';
  return { startTime, endTime, stationIds: deviceInfo.value };
});
const showLoading = ref(false);
const onDevices = async (record, type) => {
  showWitch.value = type;
  showLoading.value = true;
  // message.loading('图表生成中..', 0);
  const { pointDevices, endTime, startTime } = record;
  deviceInfo.value = pointDevices.map((i) => i.stationId);
  setTimeout(async () => {
    if (type === 'trigger') {
      try {
        const { dataInfo, deviceInfoList } = await getWaveInfo(
          deviceInfo.value,
          startTime,
          endTime,
          fetchHistoryData,
        );
        option.value.deviceInfoList = deviceInfoList;
        waveInfo.value = dataInfo;
      } catch (error) {
        showLoading.value = false;
      }
    } else {
      queryParams.value = {
        stationIds: deviceInfo.value,
        startTime,
        endTime,
      };
      const signalData = await signal(queryParams.value);
      const signalData2 = await signal(queryParams2.value);
      dataInfo.value = {
        result1: signalData.data,
        result2: signalData2.data,
      };
      init(signalData.data);
    }
    showLoading.value = false;
    flag.value = true;
  }, 300);
};

const deviceInfo = ref([]);
const showWitch = ref();
watch(
  () => showWitch.value,
  async (val) => {
    if (val === 'signalNoiseRatio') {
      if (!flag.value) return;
      const signalData = await signal(queryParams.value);
      const signalData2 = await signal(queryParams2.value);
      dataInfo.value = {
        result1: signalData.data,
        result2: signalData2.data,
      };
      init(signalData.data);
    } else if (val === 'waveform') {
      const signalData = await signal(queryParams.value);
      dataInfo.value = signalData.data;
      init(signalData.data);
    } else if (val === 'spectrum') {
      const signalData = await responseSpectrum(queryParams.value);
      dataInfo.value = signalData.data;
      init(signalData.data);
    }
  },
);
const option: any = ref({});

let params: Record<string, any> = {};
const tableRef = ref();
const canConfig = ref(false);
const handleSelectStructure = (scope) => {
  if (!scope) return;
  const { monitoringType, id } = scope;
  params = {};
  switch (monitoringType) {
    case '1':
      canConfig.value = false;
      params.netId = id;
      break;
    case '2':
      canConfig.value = false;
      params.regionId = id;
      break;
    case '3':
      canConfig.value = true;
      params.structureId = id;
      break;
  }
  tableRef.value.search();
};

const init = (data) => {
  message.destroy();
  if (!Object.keys(data).length) {
    message.info('暂无数据!');
  }

  const resultList = Object.keys(data);
  option.value.deviceInfoList = deviceInfo.value.map((i) => {
    return {
      label: i,
      value: i,
      disabled: !resultList.includes(i.replaceAll('.', '')),
    };
  });
};
</script>

<style scoped lang="scss">
.info {
  display: flex;
  flex-direction: column;
  text-align: center;
  div {
    margin-bottom: 10px;
  }
}

:deep(.ant-card-head-title) {
  padding-left: 10px;
  position: relative;
  &::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 0;
    transform: translateY(-45%);
    width: 3px;
    height: 16px;
    background-color: #0085ff;
  }
}
.modal_title {
  font-weight: 700;
  font-size: 17px;
}
</style>
